import logging
from odoo import http
from odoo.http import request

from . import api2
from . import session2

_logger = logging.getLogger(__name__)


try:
    from .zmail_ctrl import mail_handler
except Exception as e:
    print('zmail_ctrl, error ', e)
    _logger.info('zmail not install')
    mail_handler = None

# mail_handler = None


class Email(http.Controller):
    def _check_auth(self, authtype, account, method):
        if method in ['auth']:
            if authtype not in ['email', 'mobile']:
                raise ValueError('auth not email or mobile')
            if not account:
                raise ValueError('auth not email or mobile')
            return True

        if method in ['register']:
            if authtype not in ['email', 'mobile', 'login']:
                raise ValueError('regiter not email or mobile or login')
            if not account:
                raise ValueError('regiter not email or mobile or login')
            return True

        elif method in ['reset_password']:
            if authtype not in ['email', 'mobile']:
                raise ValueError('not email or mobile')
            if not account:
                raise ValueError('not email or mobile')
            return True
        else:
            raise ValueError('not register or reset_password or auth')

    @http.route('/web2/auth/codesend', type='json', auth='none', cors='*', csrf=False)
    def code_send(self, db, authtype, account, method):
        _logger.info('call email_send with %s, %s,%s,%s,',
                     db, authtype, account, method)
        self._check_auth(authtype, account, method)
        return self._code_send(db, authtype, account, method)

    @http.route('/web2/auth/codeback', type='json', auth='none', cors='*', csrf=False)
    def code_back(self, db, authtype, account, method):
        self._check_auth(authtype, account, method)
        return self._code_back(db, authtype, account)

    @http.route('/web2/auth/exist', type='json', auth='none', cors='*', csrf=False)
    def check_exist(self, db, authtype, account, method):
        self._check_auth(authtype, account, method)
        return self._check_exist(db, authtype, account)

    @http.route('/web2/auth/login', type='json', auth='none', cors='*', csrf=False)
    def auth_login(self, db, authtype, account, code):
        _logger.info('call % s: % s auth_login with db: % s, code: % s',
                     db, authtype, account, code)
        self._check_auth(authtype, account, 'auth')
        return self._auth_login(db, authtype, account, code)

    @http.route('/web2/auth/resetpsw', type='json', auth='none', cors='*', csrf=False)
    def auth_resetpsw(self, db, authtype, account, code, password):
        _logger.info('call % s: % s auth_resetpsw with db: % s, code: % s',
                     db, authtype, account, code)
        self._check_auth(authtype, account, 'auth')
        return self._resetpsw(db, authtype, account, code, password)

    @http.route('/web2/auth/register', type='json', auth='none', cors='*', csrf=False)
    def auth_register(self, db, authtype, account, code, login, password):
        _logger.info('call auth_register with %s, %s, %s',
                     db, authtype, account)
        self._check_auth(authtype, account, 'register')

        return self._register(db, authtype, account, code, login, password)

    def _code_send(self, db, field, value, sendtype):

        # mobile
        # 使用验证码登录时, 先检查 电话号码是否存在, 不存在则不发
        # 使用验证码注册时, 若电话号码已存在, 则? TBD 2020-4-27

        # email
        # 使用验证码 重置密码时, 先检查 email 是否存在, 不存在则不发
        # 使用验证码注册时, 必发
        # 若电话号码已存在, 则? TBD 2020-4-27

        env = api2.Env2(db)
        user = env['res.users'].search([(field, '=', value)], limit=1)

        if sendtype == 'auth' and not user:
            return {'error': {'message': '%s is not exist: %s' % (field, value),
                              'field': field, 'value': value}}
        if sendtype == 'register' and user:
            return {'error': {'message': '%s is exist: %s' % (field, value),
                              'field': field, 'value': value}}
        if sendtype == 'reset_password' and not user:
            return {'error': {'message': '%s is not exist: %s' % (field, value),
                              'field': field, 'value': value}}

        env = api2.Env2(db)
        code = env['res.users'].code_send(value)

        # then call email api to send msg
        if field == 'email' and mail_handler:
            print(' send 1')
            subject, content_text = user.format_mail(code, sendtype)
            print(' send 2', subject, content_text)

            mail_handler.send(value, subject, content_text)
            print(' send 4')

        # then call sms api to send msg

        # 服务端 做个配置, 这里检查配置, 返回 code 还是 状态
        return {'result': code}

    def _code_back(self, db, field, value):
        env = api2.Env2(db)
        code = env['res.users'].code_back(value)
        return code

    def _check_code(self, db, field, value, code):
        env = api2.Env2(db)
        mycode = env['res.users'].code_back(value)
        return mycode and mycode == code

    def _check_exist(self, db, field, value):
        env = api2.Env2(db)
        user = env['res.users'].search([(field, '=', value)], limit=1)
        _logger.info('call _check_exist with %s:%s, return:  %s',
                     field, value, user.id)
        return user.id

    def _auth_login(self, db, field, value, code):
        if not self._check_code(db, field, value, code):
            return None
        env = api2.Env2(db)
        env['res.users'].code_clear(value)

        return session2._auth_login(db, field, value)

    def _register(self, db, authtype, account, code, login, password):
        if not self._check_code(db, authtype, account, code):
            return None

        env = api2.Env2(db)
        env['res.users'].code_clear(account)
        ret = env['res.users'].register(db, authtype, account, login, password)
        _logger.info('call register %s,%s return:  %s', authtype, account, ret)
        return ret

    def _resetpsw(self, db, field, value, code, password):
        if not self._check_code(db, field, value, code):
            _logger.info('call _resetpsw %s,%s,%s. code error',
                         field, value, code)
            return None

        env = api2.Env2(db)
        env['res.users'].code_clear(value)
        ret = env['res.users'].reset_password(db, field, value, password)
        _logger.info('call _resetpsw %s,%s return:  %s', field, value, ret)
        return ret
